package com.yoke.common.tools;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.github.odiszapc.nginxparser.NgxBlock;
import com.github.odiszapc.nginxparser.NgxConfig;
import com.github.odiszapc.nginxparser.NgxEntry;
import com.github.odiszapc.nginxparser.NgxParam;
import com.yoke.system.log.SystemLog;
import com.yoke.util.EncryptUtil;
import com.yoke.util.FileUtil;
import com.yoke.util.StringUtil;

import java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.Stack;

/**
 * Created by jiangzeyin on 2017/7/3.
 * <p>
 * 扫描微信信息
 */
public class UrlPath {

    public enum Type {
        WeiXin,// 微信号
        Status,// 带审核状态
        None,// 所有
        Url,// 选择文案
        Rewrite, // 跳转
        Delete,
        DoMain; // 所有绑定域名
        private String path;

        public void setPath(String path) {
            this.path = path;
        }

        public String getPath() {
            return path;
        }
    }

    public static JSONArray start(String path, Type type) throws IOException {
        File file = new File(path);
        Stack<File> stack = new Stack<>();
        stack.push(file);
        JSONArray jsonArray = new JSONArray();
        // 遍历类路径
        while (!stack.isEmpty()) {
            File item = stack.pop();
            File[] subFile = item.listFiles((dir, name) -> new File(dir, name).isDirectory() || name.endsWith(".conf"));
            if (subFile != null)
                for (File itemFile : subFile) {
                    if (itemFile.isDirectory())
                        stack.push(itemFile);
                    else {
                        JSONArray temp = scannerFile(itemFile, type);
                        if (temp != null)
                            jsonArray.addAll(temp);
                    }
                }
        }
        return jsonArray;
    }

    private static JSONArray scannerFile(File file, Type type) throws IOException {
        NgxConfig conf = NgxConfig.read(file.getPath());
        List<NgxEntry> locations = conf.findAll(NgxConfig.BLOCK, "server", "location");
        NgxParam server_name = conf.findParam("server", "server_name");
        if (server_name == null)
            return null;
        List<String> stringList = server_name.getValues();
        if (stringList == null)
            return null;
        String confPath = null;
        try {
            confPath = EncryptUtil.encrypt(file.getPath());
        } catch (Exception e1) {
            SystemLog.ERROR().error("获取异常", e1);
        }
        if (type == Type.DoMain) {
            JSONArray jsonArray = new JSONArray();
            for (String item : stringList) {
                JSONObject jsonObject = new JSONObject();
                jsonObject.put("url", item);
                jsonObject.put("confPath", confPath);
                jsonArray.add(jsonObject);
            }
            return jsonArray;
        }
        return scannerUrl(stringList, locations, file.getParentFile().getName(), type, confPath);
    }

    private static JSONArray scannerUrl(List<String> rootUrl, List<NgxEntry> locations, String userName, Type type, String confPath) throws IOException {
        if (locations == null)
            return null;
        JSONArray jsonArray = new JSONArray();
        for (NgxEntry ngxEntry : locations) {
            if (ngxEntry instanceof NgxBlock) {
                NgxBlock block = (NgxBlock) ngxEntry;
                if (type == Type.Rewrite) {
                    NgxParam rewrite = block.findParam("rewrite");
                    if (rewrite == null)
                        continue;
                    List<String> values = rewrite.getValues();
                    if (values.size() == 3) {
                        String url = values.get(1);
                        if (url.endsWith("$2"))
                            url = url.substring(0, url.length() - 2);
                        JSONObject jsonObject = new JSONObject();
                        jsonObject.put("toUrl", url);
                        jsonObject.put("type", "rewrite");
                        String locUrl = rootUrl.get(0) + block.getValue();
                        jsonObject.put("url", locUrl);
                        if (rootUrl.size() > 1) {
                            jsonObject.put("urls", StringUtil.arrayToString((rootUrl.toArray(new String[0]))));
                        }
                        jsonObject.put("userName", userName);
                        jsonObject.put("confPath", confPath);
                        jsonArray.add(jsonObject);
                    }
                    continue;
                }
                NgxParam root = block.findParam("root");
                if (root == null) {
                    root = block.findParam("alias");
                    if (root == null)
                        continue;
                }
                List<String> rootValues = block.getValues();
                if (rootValues.size() == 1) {
                    JSONArray fileArray = scannerDir(rootUrl, root.getValue(), root.getValue(), userName, type, confPath);
                    if (fileArray != null)
                        jsonArray.addAll(fileArray);
                }
            }
        }
        return jsonArray;
    }

    private static JSONArray scannerDir(List<String> rootUrls, String root, String path, String userName, Type type, String confPath) throws IOException {
        File file = new File(path);
        Stack<File> stack = new Stack<>();
        stack.push(file);
        JSONArray jsonArray = new JSONArray();
        String rootUrl = rootUrls.get(0);
        while (!stack.isEmpty()) {
            File item = stack.pop();
            File[] subFile = item.listFiles((dir, name) -> {
                if (dir.isDirectory() || "index.html".equals(name))
                    return true;
                if (type == Type.Delete)
                    if ("index_back.html".equals(name))
                        return true;
                return false;
            });
            if (subFile == null)
                continue;
            for (File itemFile : subFile) {
                if (itemFile.isDirectory()) {
                    stack.push(itemFile);
                    continue;
                }
                if (type != Type.Delete && "index.html".equals(itemFile.getName())) {
                    JSONObject jsonObject = new JSONObject();
                    String url = FileUtil.ClearPath(rootUrl + "/" + FileUtil.ClearPath(itemFile.getPath()).replace(root, ""));
                    jsonObject.put("url", url);
                    if (rootUrls.size() > 1) {
                        jsonObject.put("urls", StringUtil.arrayToString((rootUrls.toArray(new String[0]))));
                    }
                    String editPath = null;
                    try {
                        editPath = EncryptUtil.encrypt(FileUtil.ClearPath(itemFile.getPath()));
                    } catch (Exception e1) {
                        SystemLog.ERROR().error("系统异常", e1);
                    }
                    switch (type) {
                        case None:
                            jsonObject.put("editPath", editPath);
                            break;
                        case WeiXin:
                            String weixin = FileUtil.readToString(itemFile);
                            if (StringUtil.IsEmpty(weixin))
                                continue;
                            int s = weixin.indexOf("<!--weixin-->");
                            int e = weixin.indexOf("<!--weixin_end-->");
                            if (s == -1 || e == -1)
                                continue;
                            if (e < s)
                                continue;
                            // System.out.println(itemFile.getPath());
                            jsonObject.put("weixinPath", editPath);
                            break;
                        case Status:
                            File shFile = new File(itemFile.getParent(), "index_sh.html");
                            File tfFile = new File(itemFile.getParent(), "index_tf.html");
                            if (shFile.exists() || tfFile.exists()) {
                                jsonObject.put("status", shFile.exists() ? "tf" : tfFile.exists() ? "sh" : null);
                                try {
                                    String uPath = EncryptUtil.encrypt(FileUtil.ClearPath(itemFile.getParent()));
                                    jsonObject.put("urlPath", uPath);
                                } catch (Exception e1) {
                                    SystemLog.ERROR().error("获取异常", e1);
                                }
                            } else {
                                continue;
                            }
                            break;
                        case Url:
                            String filePath = FileUtil.ClearPath(itemFile.getPath());
                            if (!filePath.equals(type.getPath()))
                                continue;
                            filePath = FileUtil.ClearPath(itemFile.getParent());
                            String product = filePath.replace(root, "/");
                            jsonObject.put("product", product);
                            break;
                    }
                    jsonObject.put("confPath", confPath);
                    jsonObject.put("userName", userName);
                    jsonArray.add(jsonObject);
                } else if (type == Type.Delete) {
                    if ("index_back.html".equals(itemFile.getName())) {
                        JSONObject jsonObject = new JSONObject();
                        String editPath = null;
                        try {
                            editPath = EncryptUtil.encrypt(FileUtil.ClearPath(itemFile.getPath()));
                        } catch (Exception e1) {
                            SystemLog.ERROR().error("系统异常", e1);
                        }
                        jsonObject.put("editPath", editPath);
                        File temp = new File(itemFile.getParentFile(), "index.html");
                        String url = FileUtil.ClearPath(rootUrl + "/" + FileUtil.ClearPath(temp.getPath()).replace(root, ""));
                        jsonObject.put("url", url);
                        if (rootUrls.size() > 1) {
                            jsonObject.put("urls", StringUtil.arrayToString((rootUrls.toArray(new String[0]))));
                        }
                        jsonObject.put("userName", userName);
                        jsonArray.add(jsonObject);
                    }
                }
            }
        }
        return jsonArray;
    }
}
